<?php

namespace service\proxy;

use service\proxy\curl;
use service\proxy\proxylist as ProxyPool;

abstract class proxy
{
    /**
     *
     * @param  string $url
     * @param  string|null $proxy
     * @param  array  $_options
     * @return mixed
     */
    public function get($url, $proxy = null, array $_options = [])
    {
        return $this->requst($url, $proxy, [] ,'get', $_options);
    }
    /**
     *
     * @param  string $url
     * @param  string|null $proxy
     * @param  array  $data
     * @param  array  $_options
     * @return mixed
     */
    public function post($url, $proxy = null, $data = [], array $_options = [])
    {
        return $this->requst($url, $proxy, $data, 'post', $_options);
    }

    /**
     *
     * @param  string $url
     * @param  string|null $proxy
     * @param  array  $data
     * @param  string $type
     * @param  array  $_options
     * @return mixed
     */
    public function requst($url, $proxy = null, $data = [], $type = 'get', array $_options = [])
    {

        if (!$url) {
            return false;
        }
        $header = [
            // "DNT: 1" ,
            // "Accept-Encoding: deflate, sdch" ,
            "Accept-Language: zh-CN,zh;q=0.8",
            // "User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2816.0 Safari/537.36",
            "Accept: */*",
            "Cache-Control: no-cache",
            "X-Requested-With: XMLHttpRequest",
            // "Proxy-Connection: keep-alive" ,
            "Referer: http://www.kuaidi100.com/",
        ];

        //curl_setopt($ch, CURLOPT_PROXYUSERPWD, $this->proxyauth);
        if ($proxy !== null && !preg_match('#(?:\d{1,3}\.){3}(?:\d{1,3}:[1-9]\d*)#i', $proxy) && !($proxy = $tmp_proxy = ProxyPool::getInstance('common_proxy_pool')->get())) {
            //log no proxy set,and no proxy get
            return false;
        }
        $proxy AND $_options[CURLOPT_PROXY] = $proxy;
        !isset($_options[CURLOPT_TIMEOUT]) AND $_options[CURLOPT_TIMEOUT] = 3;
        isset($_options[CURLOPT_USERAGENT]) or $_options[CURLOPT_USERAGENT] = $this->getRadomUserAgentString();
        $type = trim($type);
        if (in_array(strtolower($type), ['get', 'post'])) {
            if ($return = curl::request($url, $data, $type, $_options)) {
                return (array) $return + ['proxy_ip' => $proxy];
            } else {
                $error = curl::get_error();
                $this->setError((array) $error + ['proxy_ip' => $proxy]);
            }
        } else {
            var_dump(func_get_args());
            //log no request method was supported
        }
    }



    /**
     * get a random User Agent string
     *
     * @see http://www.useragentstring.com/pages/useragentstring.php
     * @return string
     */
    private function getRadomUserAgentString()
    {
        $ua = [
            'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2816.0 Safari/537.36',
            'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko',
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2311.135 Safari/537.36 Edge/12.246',
            'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1',
            'Mozilla/5.0 (BlackBerry; U; BlackBerry 9900; en) AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.1.0.346 Mobile Safari/534.11+',
            'Mozilla/5.0 (Linux; U; Android 4.0.3; ko-kr; LG-L160L Build/IML74K) AppleWebkit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',
            'Opera/9.80 (J2ME/MIDP; Opera Mini/9.80 (S60; SymbOS; Opera Mobi/23.348; U; en) Presto/2.5.25 Version/10.54',
            'Opera/9.80 (X11; Linux i686; Ubuntu/14.10) Presto/2.12.388 Version/12.16',
            'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0) Opera 12.14',
            'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/7046A194A',
        ];
        return $ua[array_rand($ua)];
    }

    /**
     * getCurlError
     *
     * @return array
     */
    public function getCurlError()
    {
        return curl::get_error();
    }

    /**
     * getError
     *
     * @param string $key
     * @return array
     */
    public function getError($key = null)
    {
        return is_string($key) && isset($this->errors[$key]) ? $this->errors[$key] : $this->errors;
    }

    /**
     * setError
     *
     * @param mixed $errors
     * @param string $key
     * @return bool
     */
    public function setError($errors, $key = null)
    {
        if((bool) $errors){
            $key = (string) $key ? : (string) microtime(true);
            $this->errors[$key] = $errors;
            return true;
        }
        return false;
    }

    /**
     * getLastError
     *
     * @return mixed
     */
    public function getLastError()
    {
        return is_array($this->errors) ? end($this->errors): null;
    }
}
